<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Flink入门学习 | Cquang博客</title><meta name="keywords" content="flink,大数据"><meta name="author" content="Cai XianQuan"><meta name="copyright" content="Cai XianQuan"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta http-equiv="Cache-Control" content="no-transform"><meta http-equiv="Cache-Control" content="no-siteapp"><meta name="description" content="学习尚硅谷Flink视频，总结Flink知识点，入门学习">
<meta property="og:type" content="article">
<meta property="og:title" content="Flink入门学习">
<meta property="og:url" content="https://xquan123.gitee.io/2020/12/13/Flink%E5%85%A5%E9%97%A8%E5%AD%A6%E4%B9%A0/index.html">
<meta property="og:site_name" content="Cquang博客">
<meta property="og:description" content="学习尚硅谷Flink视频，总结Flink知识点，入门学习">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://xquan123.gitee.io/2020/12/13/Flink%E5%85%A5%E9%97%A8%E5%AD%A6%E4%B9%A0/Flink%E5%85%A5%E9%97%A8%E5%AD%A6%E4%B9%A0%E9%A6%96%E9%A1%B5.png">
<meta property="article:published_time" content="2020-12-13T10:21:57.000Z">
<meta property="article:modified_time" content="2021-01-28T06:31:55.786Z">
<meta property="article:author" content="Cai XianQuan">
<meta property="article:tag" content="大数据">
<meta property="article:tag" content="flink">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://xquan123.gitee.io/2020/12/13/Flink%E5%85%A5%E9%97%A8%E5%AD%A6%E4%B9%A0/Flink%E5%85%A5%E9%97%A8%E5%AD%A6%E4%B9%A0%E9%A6%96%E9%A1%B5.png"><link rel="shortcut icon" href="/blog/img/favicon1.png"><link rel="canonical" href="https://xquan123.gitee.io/2020/12/13/Flink%E5%85%A5%E9%97%A8%E5%AD%A6%E4%B9%A0/"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//fonts.googleapis.com" crossorigin="crossorigin"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="stylesheet" href="/blog/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.css"><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Titillium+Web"><script>var GLOBAL_CONFIG = { 
  root: '/blog/',
  algolia: undefined,
  localSearch: {"path":"search.xml","languages":{"hits_empty":"找不到您查询的内容：${query}"}},
  translate: {"defaultEncoding":2,"translateDelay":0,"msgToTraditionalChinese":"繁","msgToSimplifiedChinese":"簡"},
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: false,
    post: false
  },
  runtime: '天',
  date_suffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: undefined,
  ClickShowText: undefined,
  lightbox: 'mediumZoom',
  Snackbar: {"chs_to_cht":"你已切换为繁体","cht_to_chs":"你已切换为简体","day_to_night":"你已切换为深色模式","night_to_day":"你已切换为浅色模式","bgLight":"#49b1f5","bgDark":"#121212","position":"bottom-left"},
  justifiedGallery: {
    js: 'https://cdn.jsdelivr.net/npm/justifiedGallery/dist/js/jquery.justifiedGallery.min.js',
    css: 'https://cdn.jsdelivr.net/npm/justifiedGallery/dist/css/justifiedGallery.min.css'
  },
  isPhotoFigcaption: true,
  islazyload: false,
  isanchor: false
};

var saveToLocal = {
  set: function setWithExpiry(key, value, ttl) {
    const now = new Date()
    const expiryDay = ttl * 86400000
    const item = {
      value: value,
      expiry: now.getTime() + expiryDay,
    }
    localStorage.setItem(key, JSON.stringify(item))
  },

  get: function getWithExpiry(key) {
    const itemStr = localStorage.getItem(key)

    if (!itemStr) {
      return undefined
    }
    const item = JSON.parse(itemStr)
    const now = new Date()

    if (now.getTime() > item.expiry) {
      localStorage.removeItem(key)
      return undefined
    }
    return item.value
  }
}</script><script id="config_change">var GLOBAL_CONFIG_SITE = { 
  isPost: true,
  isHome: false,
  isHighlightShrink: true,
  isToc: true,
  postUpdate: '2021-01-28 14:31:55'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(function () {  window.activateDarkMode = function () {
    document.documentElement.setAttribute('data-theme', 'dark')
    if (document.querySelector('meta[name="theme-color"]') !== null) {
      document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
    }
  }
  window.activateLightMode = function () {
    document.documentElement.setAttribute('data-theme', 'light')
   if (document.querySelector('meta[name="theme-color"]') !== null) {
      document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
    }
  }
  const autoChangeMode = 'false'
  const t = saveToLocal.get('theme')
  if (autoChangeMode === '1') {
    const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches
    const isLightMode = window.matchMedia('(prefers-color-scheme: light)').matches
    const isNotSpecified = window.matchMedia('(prefers-color-scheme: no-preference)').matches
    const hasNoSupport = !isDarkMode && !isLightMode && !isNotSpecified
    if (t === undefined) {
      if (isLightMode) activateLightMode()
      else if (isDarkMode) activateDarkMode()
      else if (isNotSpecified || hasNoSupport) {
        const now = new Date()
        const hour = now.getHours()
        const isNight = hour <= 6 || hour >= 18
        isNight ? activateDarkMode() : activateLightMode()
      }
      window.matchMedia('(prefers-color-scheme: dark)').addListener(function (e) {
        if (saveToLocal.get('theme') === undefined) {
          e.matches ? activateDarkMode() : activateLightMode()
        }
      })
    } else if (t === 'light') activateLightMode()
    else activateDarkMode()
  } else if (autoChangeMode === '2') {
    const now = new Date()
    const hour = now.getHours()
    const isNight = hour <= 6 || hour >= 18
    if (t === undefined) isNight ? activateDarkMode() : activateLightMode()
    else if (t === 'light') activateLightMode()
    else activateDarkMode()
  } else {
    if (t === 'dark') activateDarkMode()
    else if (t === 'light') activateLightMode()
  }const asideStatus = saveToLocal.get('aside-status')
if (asideStatus !== undefined) {
   if (asideStatus === 'hide') {
     document.documentElement.classList.add('hide-aside')
   } else {
     document.documentElement.classList.remove('hide-aside')
   }
}})()</script><link rel="stylesheet" href="/css/VolantisTags.css"><meta name="generator" content="Hexo 5.3.0"></head><body><div id="web_bg"></div><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="author-avatar"><img class="avatar-img" src="/blog/img/%E5%A4%B4%E5%83%8F.gif" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="site-data"><div class="data-item is-center"><div class="data-item-link"><a href="/blog/archives/"><div class="headline">文章</div><div class="length-num">22</div></a></div></div><div class="data-item is-center"><div class="data-item-link"><a href="/blog/tags/"><div class="headline">标签</div><div class="length-num">33</div></a></div></div><div class="data-item is-center"><div class="data-item-link"><a href="/blog/categories/"><div class="headline">分类</div><div class="length-num">18</div></a></div></div></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/blog/"><i class="fa-fw fas fa-home"></i><span> 主页</span></a></div><div class="menus_item"><a class="site-page" href="/blog/archives/"><i class="fa-fw fas fa-archive"></i><span> 时间轴</span></a></div><div class="menus_item"><a class="site-page" href="/blog/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/blog/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="javascript:void(0);"><i class="fa-fw fas fa-list"></i><span> 享受时光</span><i class="fas fa-chevron-down expand"></i></a><ul class="menus_item_child"><li><a class="site-page" href="/blog/music/"><i class="fa-fw fas fa-music"></i><span> 音乐</span></a></li></ul></div></div></div></div><div id="body-wrap"><header class="post-bg" id="page-header" style="background-image: url(/blog/2020/12/13/Flink%E5%85%A5%E9%97%A8%E5%AD%A6%E4%B9%A0/Flink%E5%85%A5%E9%97%A8%E5%AD%A6%E4%B9%A0%E9%A6%96%E9%A1%B5.png)"><nav id="nav"><span id="blog_name"><a id="site-name" href="/blog/">Cquang博客</a></span><span id="menus"><div id="search_button"><a class="site-page social-icon search"><i class="fas fa-search fa-fw"></i><span> 搜索</span></a></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/blog/"><i class="fa-fw fas fa-home"></i><span> 主页</span></a></div><div class="menus_item"><a class="site-page" href="/blog/archives/"><i class="fa-fw fas fa-archive"></i><span> 时间轴</span></a></div><div class="menus_item"><a class="site-page" href="/blog/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/blog/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="javascript:void(0);"><i class="fa-fw fas fa-list"></i><span> 享受时光</span><i class="fas fa-chevron-down expand"></i></a><ul class="menus_item_child"><li><a class="site-page" href="/blog/music/"><i class="fa-fw fas fa-music"></i><span> 音乐</span></a></li></ul></div></div><span class="close" id="toggle-menu"><a class="site-page"><i class="fas fa-bars fa-fw"></i></a></span></span></nav><div id="post-info"><h1 class="post-title">Flink入门学习</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2020-12-13T10:21:57.000Z" title="发表于 2020-12-13 18:21:57">2020-12-13</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2021-01-28T06:31:55.786Z" title="更新于 2021-01-28 14:31:55">2021-01-28</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/blog/categories/%E5%A4%A7%E6%95%B0%E6%8D%AE%E5%AD%A6%E4%B9%A0/">大数据学习</a><i class="fas fa-angle-right post-meta-separator"></i><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/blog/categories/%E5%A4%A7%E6%95%B0%E6%8D%AE%E5%AD%A6%E4%B9%A0/%E5%B0%9A%E7%A1%85%E8%B0%B7%E5%A4%A7%E6%95%B0%E6%8D%AE%E4%B9%8BFlink%E5%AD%A6%E4%B9%A0/">尚硅谷大数据之Flink学习</a></span></div><div class="meta-secondline"> <span class="post-meta-separator">|</span><span class="post-meta-wordcount"><i class="far fa-file-word fa-fw post-meta-icon"></i><span class="post-meta-label">字数总计:</span><span class="word-count">6.1k</span><span class="post-meta-separator">|</span><i class="far fa-clock fa-fw post-meta-icon"></i><span class="post-meta-label">阅读时长:</span><span>24分钟</span></span><span class="post-meta-separator">|</span><span class="post-meta-pv-cv"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"></span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><div class="note info flat"><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line">--头部属性说明：</span><br><span class="line">title	【必需】文章标题【需要】</span><br><span class="line">date	【必需】文章创建日期【需要】</span><br><span class="line">tags	【可选】文章标签【需要】</span><br><span class="line">categories	【可选】文章分类【需要】</span><br><span class="line">keywords	【可选】文章关键字【需要，同标签】</span><br><span class="line">description	【可选】文章描述【需要】</span><br><span class="line">top_img	【可选】文章顶部图片</span><br><span class="line">cover	【可选】文章缩略图(如果没有设置top_img,文章页顶部将显示缩略图，可设为false/图片地址/留空)【需要，地址为：/年/月/日/文章生成的文件夹名/图片名称.后缀名】</span><br><span class="line">comments	【可选】显示文章评论模块(默认 true)</span><br><span class="line">toc	【可选】显示文章TOC(默认为设置中toc的enable配置)</span><br><span class="line">toc_number	【可选】显示</span><br><span class="line">toc_number	(默认为设置中toc的number配置)</span><br><span class="line">copyright	【可选】显示文章版权模块(默认 true)</span><br><span class="line">mathjax	【可选】显示mathjax(当设置mathjax的per_page: false时，才需要配置，默认 false)</span><br><span class="line">katex	【可选】显示katex(当设置katex的per_page: false时，才需要配置，默认 false)</span><br><span class="line"></span><br><span class="line">--标签外挂</span><br><span class="line">样式：</span><br><span class="line">[class] : default | primary | success | info | warning | danger.</span><br><span class="line">&#123;% note info %&#125;</span><br><span class="line">编辑内容</span><br><span class="line">&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">--图片插入示例：</span><br><span class="line">不显示描述，可以插入【舍弃不用】：</span><br><span class="line">&#123;% asset_img example.png %&#125;</span><br><span class="line">显示描述的：</span><br><span class="line">![example](example.png)	不用添加路径，直接填图片名称即可，将图片放入对应文件夹内</span><br><span class="line"></span><br><span class="line">-- 插入链接</span><br><span class="line">&#123;% link text url [external] [title] %&#125;</span><br><span class="line"></span><br><span class="line">--</span><br><span class="line">参考地址：[git 无法添加文件夹下文件](https://www.cnblogs.com/howdop/p/5583342.html)</span><br></pre></td></tr></table></figure></div>

<h1 id="Flink简介"><a href="#Flink简介" class="headerlink" title="Flink简介"></a>Flink简介</h1><h2 id="大数据框架的发展历程"><a href="#大数据框架的发展历程" class="headerlink" title="大数据框架的发展历程"></a>大数据框架的发展历程</h2><p><img src="1%E3%80%81%E5%A4%A7%E6%95%B0%E6%8D%AE%E6%A1%86%E6%9E%B6%E7%9A%84%E5%8F%91%E5%B1%95%E5%8E%86%E7%A8%8B.png" alt="大数据框架的发展历程"></p>
<ul>
<li>Flink已经是一个实时计算框架，而spark中的spark Streaming其实还是一个伪实时的计算框架【处理数据一般在500ms以内,开窗口最小的窗口也需要500ms】，属于微批处理。</li>
</ul>
<h2 id="初识Flink"><a href="#初识Flink" class="headerlink" title="初识Flink"></a>初识Flink</h2><ol>
<li>Flink项目的理念是：“<font color=red size=3><strong>Apache Flink是为分布式、高性能、随时可用以及准确的流处理应用程序打造的开源流处理框架</strong></font>”。</li>
<li>Apache Flink是一个框架和分布式处理引擎，用于对<font color=red size=3><strong>无界和有界数据流</strong></font>进行有<font color=red size=3><strong>状态</strong></font>计算。Flink被设计在所有常见的集群环境中运行，以内存执行速度和任意规模来执行计算。</li>
</ol>
<h3 id="选择Flink的理由"><a href="#选择Flink的理由" class="headerlink" title="选择Flink的理由"></a>选择Flink的理由</h3><ol>
<li>流数据更真实地反映了我们的生活方式</li>
<li>传统的数据架构是基于有限数据集的</li>
<li>我们的目标</li>
</ol>
<ul>
<li>低延迟【spark stream的延迟是秒级，Flink延迟是毫秒级】</li>
<li>高吞吐【阿里每秒钟使用Flink处理4.6PB，双十一大屏】</li>
<li>结果的准确性和良好的容错性【exactly-once】</li>
</ul>
<h3 id="哪些行业需要处理流数据"><a href="#哪些行业需要处理流数据" class="headerlink" title="哪些行业需要处理流数据"></a>哪些行业需要处理流数据</h3><div class="note primary flat"><p>基本全部行业都需要流处理数据</p>
</div>
<ol>
<li>电商和市场营销<ul>
<li>数据报表、广告投放、业务流程需要</li>
</ul>
</li>
<li>物联网（IOT）<ul>
<li>传感器实时数据采集和显示、实时报警，交通运输业</li>
</ul>
</li>
<li>电信业<ul>
<li>基站流量调配</li>
</ul>
</li>
<li>银行和金融业<ul>
<li>实时结算和通知推送，实时检测异常行为</li>
</ul>
</li>
</ol>
<h2 id="Flink的重要特点"><a href="#Flink的重要特点" class="headerlink" title="Flink的重要特点"></a>Flink的重要特点</h2><h3 id="事件驱动型-Event-driven"><a href="#事件驱动型-Event-driven" class="headerlink" title="事件驱动型(Event-driven)"></a>事件驱动型(Event-driven)</h3><p>事件驱动型应用是一类具有状态的应用，它从一个或多个事件流提取数据，并根据到来的事件触发计算、状态更新或其他外部动作。比较典型的就是以kafka为代表的消息队列几乎都是事件驱动型应用。</p>
<ul>
<li>与之不同的就是SparkStreaming微批次，如图：<br><img src="2%E3%80%81SparkStreaming%E5%BE%AE%E6%89%B9%E6%AC%A1.png" alt="SparkStreaming微批次"></li>
<li>事件驱动型：<br><img src="3%E3%80%81%E4%BA%8B%E4%BB%B6%E9%A9%B1%E5%8A%A8%E5%9E%8B.png" alt="事件驱动型"></li>
</ul>
<h3 id="流与批的世界观"><a href="#流与批的世界观" class="headerlink" title="流与批的世界观"></a>流与批的世界观</h3><ol>
<li><strong><em>批处理</em></strong>的特点是有界、持久、大量，非常适合需要访问全套记录才能完成的计算工作，一般用于离线统计。</li>
<li><strong><em>流处理</em></strong>的特点是无界、实时,  无需针对整个数据集执行操作，而是对通过系统传输的每个数据项执行操作，一般用于实时统计。<ul>
<li>在<strong>spark</strong> 的世界观中，一切都是由批次组成的，离线数据是一个大批次，而实时数据是由一个一个无限的小批次组成的。</li>
<li>而在<strong>flink</strong> 的世界观中，一切都是由流组成的，离线数据是有界限的流，实时数据是一个没有界限的流，这就是所谓的有界流和无界流。</li>
</ul>
</li>
<li><strong><em>无界数据流</em></strong>：无界数据流有一个开始但是没有结束，它们不会在生成时终止并提供数据，必须连续处理无界流，也就是说必须在获取后立即处理event。对于无界数据流我们无法等待所有数据都到达，因为输入是无界的，并且在任何时间点都不会完成。处理无界数据通常要求以特定顺序（例如事件发生的顺序）获取event，以便能够推断结果完整性。</li>
<li><strong><em>有界数据流</em></strong>：有界数据流有明确定义的开始和结束，可以在执行任何计算之前通过获取所有数据来处理有界流，处理有界流不需要有序获取，因为可以始终对有界数据集进行排序，有界流的处理也称为批处理。<br><img src="4%E3%80%81%E6%9C%89%E7%95%8C%E5%92%8C%E6%97%A0%E7%95%8C%E6%95%B0%E6%8D%AE%E6%B5%81.png" alt="有界和无界数据流"><br><font color=red size=3><strong>这种以流为世界观的架构，获得的最大好处就是具有极低的延迟。</strong></font></li>
</ol>
<h3 id="分层api"><a href="#分层api" class="headerlink" title="分层api"></a>分层api</h3><p><img src="5%E3%80%81%E5%88%86%E5%B1%82API.png" alt="分层API"></p>
<ol>
<li>最底层级的抽象仅仅提供了有状态流，它将通过过程函数（Process Function）被嵌入到DataStream API中。底层过程函数（Process Function） 与 DataStream API 相集成，使其可以对某些特定的操作进行底层的抽象，它允许用户可以自由地处理来自一个或多个数据流的事件，并使用一致的容错的状态。除此之外，用户可以注册事件时间并处理时间回调，从而使程序可以处理复杂的计算。</li>
<li>实际上，大多数应用并不需要上述的底层抽象，而是针对核心API（Core APIs） 进行编程，比如DataStream API（有界或无界流数据）以及DataSet API（有界数据集）。这些API为数据处理提供了通用的构建模块，比如由用户定义的多种形式的转换（transformations），连接（joins），聚合（aggregations），窗口操作（windows）等等。DataSet API 为有界数据集提供了额外的支持，例如循环与迭代。这些API处理的数据类型以类（classes）的形式由各自的编程语言所表示。</li>
<li>Table API 是以表为中心的声明式编程，其中表可能会动态变化（在表达流数据时）。Table API遵循（扩展的）关系模型：表有二维数据结构（schema）（类似于关系数据库中的表），同时API提供可比较的操作，例如select、project、join、group-by、aggregate等。Table API程序声明式地定义了什么逻辑操作应该执行，而不是准确地确定这些操作代码的看上去如何。</li>
<li>尽管Table API可以通过多种类型的用户自定义函数（UDF）进行扩展，其仍不如核心API更具表达能力，但是使用起来却更加简洁（代码量更少）。除此之外，Table API程序在执行之前会经过内置优化器进行优化。</li>
<li>你可以在表与 DataStream/DataSet 之间无缝切换，以允许程序将 Table API 与 DataStream 以及 DataSet 混合使用。</li>
<li>Flink提供的最高层级的抽象是 SQL 。这一层抽象在语法与表达能力上与 Table API 类似，但是是以SQL查询表达式的形式表现程序。SQL抽象与Table API交互密切，同时SQL查询可以直接在Table API定义的表上执行。</li>
<li>目前Flink作为批处理还不是主流，不如Spark成熟，所以DataSet使用的并不是很多。Flink Table API和Flink SQL也并不完善，大多都由各大厂商自己定制。所以我们主要学习DataStream API的使用。实际上Flink作为最接近Google DataFlow模型的实现，是流批统一的观点，所以基本上使用DataStream就可以了。</li>
<li>Flink几大模块<ul>
<li>Flink Table &amp; SQL(还没开发完)</li>
<li>Flink Gelly(图计算)</li>
<li>Flink CEP(复杂事件处理)</li>
</ul>
</li>
</ol>
<h3 id="Flink的其他特点"><a href="#Flink的其他特点" class="headerlink" title="Flink的其他特点"></a>Flink的其他特点</h3><ol>
<li>支持事件时间（event-time）和处理时间（processing-time）语义</li>
<li>精确一次（exactly-once）的状态一致性保证</li>
<li>低延迟，每秒处理数百万个事件，毫秒级延迟</li>
<li>与众多常用存储系统的连接</li>
<li>高可用，动态扩展，实现7*24小时全天候运行</li>
</ol>
<h1 id="wordCount程序"><a href="#wordCount程序" class="headerlink" title="wordCount程序"></a>wordCount程序</h1><h2 id="需求说明"><a href="#需求说明" class="headerlink" title="需求说明"></a>需求说明</h2><ol>
<li>通过nc命令产生测试数据，flink监听端口，开启一个5s的滚动窗口，5s内统计一次wordcount</li>
</ol>
<h2 id="程序编写"><a href="#程序编写" class="headerlink" title="程序编写"></a>程序编写</h2><div class="note info flat"><p>本项目使用的Flink版本为最新版本，也就是1.11.0。现在提供maven项目的配置文件。</p>
</div>
<ol>
<li>使用Intellij IDEA创建一个Maven新项目</li>
<li>勾选<code>Create from archetype</code>，然后点击<code>Add Archetype</code>按钮</li>
<li><code>GroupId</code>中输入<code>org.apache.flink</code>，<code>ArtifactId</code>中输入<code>flink-quickstart-scala</code>，<code>Version</code>中输入<code>1.11.0</code>，然后点击<code>OK</code></li>
<li>点击向右箭头，出现下拉列表，选中<code>flink-quickstart-scala:1.11.0</code>，点击<code>Next</code></li>
<li><code>Name</code>中输入<code>FlinkTutorial</code>，<code>GroupId</code>中输入<code>com.caixianquan</code>，<code>ArtifactId</code>中输入<code>FlinkTutorial</code>，点击<code>Next</code></li>
<li>最好使用IDEA默认的Maven工具：Bundled（Maven 3），点击<code>Finish</code>，等待一会儿，项目就创建好了</li>
<li>新建一个scala文件：WordCount<figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.caixianquan</span><br><span class="line"></span><br><span class="line"><span class="comment">//导入一些隐式类型转换，implicit</span></span><br><span class="line"><span class="keyword">import</span> org.apache.flink.streaming.api.scala._</span><br><span class="line"><span class="keyword">import</span> org.apache.flink.streaming.api.windowing.time.<span class="type">Time</span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">object</span> <span class="title">WordCount</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">case</span> <span class="class"><span class="keyword">class</span> <span class="title">WordWithCount</span>(<span class="params">word: <span class="type">String</span>, count: <span class="type">Int</span></span>)</span></span><br><span class="line"><span class="class"></span></span><br><span class="line"><span class="class">  <span class="title">def</span> <span class="title">main</span>(<span class="params">args: <span class="type">Array</span>[<span class="type">String</span>]</span>)</span>: <span class="type">Unit</span> = &#123;</span><br><span class="line">    <span class="comment">//获取运行时环境，类似SparkContext</span></span><br><span class="line">    <span class="keyword">val</span> env: <span class="type">StreamExecutionEnvironment</span> = <span class="type">StreamExecutionEnvironment</span>.getExecutionEnvironment</span><br><span class="line">    <span class="comment">//设置分区（并行任务）的数量为1</span></span><br><span class="line">    env.setParallelism(<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line">    <span class="comment">//建立数据源</span></span><br><span class="line">    <span class="comment">//需要先启动`nc -lk 9999`, 用来发送数据</span></span><br><span class="line">    <span class="keyword">val</span> stream = env.socketTextStream(<span class="string">&quot;hadoop101&quot;</span>, <span class="number">9999</span>, &#x27;\n&#x27;)</span><br><span class="line"></span><br><span class="line">    <span class="comment">//写对流的转换处理逻辑</span></span><br><span class="line">    <span class="keyword">val</span> transformed = stream</span><br><span class="line">    <span class="comment">//使用空格切分输入的字符串</span></span><br><span class="line">      .flatMap(line=&gt; line.split(<span class="string">&quot;\\s&quot;</span>))</span><br><span class="line">      <span class="comment">//类似于MR中的map</span></span><br><span class="line">      .map(w =&gt; <span class="type">WordWithCount</span>(w, <span class="number">1</span>))</span><br><span class="line">    <span class="comment">//使用word字段进行分组， shuffle</span></span><br><span class="line">      .keyBy(<span class="string">&quot;word&quot;</span>)</span><br><span class="line">    <span class="comment">//开了一个5s钟的滚动窗口</span></span><br><span class="line">      .timeWindow(<span class="type">Time</span>.seconds(<span class="number">5</span>))</span><br><span class="line">      .sum(<span class="string">&quot;count&quot;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="comment">//将计算的结果输出到标准输出</span></span><br><span class="line">    transformed.print()</span><br><span class="line"></span><br><span class="line">    <span class="comment">//执行计算逻辑</span></span><br><span class="line">    env.execute()</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h2 id="pom文件修改"><a href="#pom文件修改" class="headerlink" title="pom文件修改"></a>pom文件修改</h2></li>
<li>自动生成的pom文件依赖包中都带有<scope>provided</scope>属性,该属性表示打包时不带上这些依赖包，环境已提供，故在运行程序时也需要注释掉该属性，程序才能正确调用依赖包</li>
<li>pom文件修改后内容<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">Licensed to the Apache Software Foundation (ASF) under one</span></span><br><span class="line"><span class="comment">or more contributor license agreements.  See the NOTICE file</span></span><br><span class="line"><span class="comment">distributed with this work for additional information</span></span><br><span class="line"><span class="comment">regarding copyright ownership.  The ASF licenses this file</span></span><br><span class="line"><span class="comment">to you under the Apache License, Version 2.0 (the</span></span><br><span class="line"><span class="comment">&quot;License&quot;); you may not use this file except in compliance</span></span><br><span class="line"><span class="comment">with the License.  You may obtain a copy of the License at</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">  http://www.apache.org/licenses/LICENSE-2.0</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">Unless required by applicable law or agreed to in writing,</span></span><br><span class="line"><span class="comment">software distributed under the License is distributed on an</span></span><br><span class="line"><span class="comment">&quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY</span></span><br><span class="line"><span class="comment">KIND, either express or implied.  See the License for the</span></span><br><span class="line"><span class="comment">specific language governing permissions and limitations</span></span><br><span class="line"><span class="comment">under the License.</span></span><br><span class="line"><span class="comment">--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">project</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://maven.apache.org/POM/4.0.0&quot;</span></span></span><br><span class="line"><span class="tag">         <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">         <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&quot;</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">modelVersion</span>&gt;</span>4.0.0<span class="tag">&lt;/<span class="name">modelVersion</span>&gt;</span></span><br><span class="line"></span><br><span class="line">	<span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.example<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>FlinkTutorial<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">version</span>&gt;</span>1.0-SNAPSHOT<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">packaging</span>&gt;</span>jar<span class="tag">&lt;/<span class="name">packaging</span>&gt;</span></span><br><span class="line"></span><br><span class="line">	<span class="tag">&lt;<span class="name">name</span>&gt;</span>Flink Quickstart Job<span class="tag">&lt;/<span class="name">name</span>&gt;</span></span><br><span class="line"></span><br><span class="line">	<span class="tag">&lt;<span class="name">repositories</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">repository</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">id</span>&gt;</span>apache.snapshots<span class="tag">&lt;/<span class="name">id</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">name</span>&gt;</span>Apache Development Snapshot Repository<span class="tag">&lt;/<span class="name">name</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">url</span>&gt;</span>https://repository.apache.org/content/repositories/snapshots/<span class="tag">&lt;/<span class="name">url</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">releases</span>&gt;</span></span><br><span class="line">				<span class="tag">&lt;<span class="name">enabled</span>&gt;</span>false<span class="tag">&lt;/<span class="name">enabled</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;/<span class="name">releases</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">snapshots</span>&gt;</span></span><br><span class="line">				<span class="tag">&lt;<span class="name">enabled</span>&gt;</span>true<span class="tag">&lt;/<span class="name">enabled</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;/<span class="name">snapshots</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;/<span class="name">repository</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;/<span class="name">repositories</span>&gt;</span></span><br><span class="line"></span><br><span class="line">	<span class="tag">&lt;<span class="name">properties</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">project.build.sourceEncoding</span>&gt;</span>UTF-8<span class="tag">&lt;/<span class="name">project.build.sourceEncoding</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">flink.version</span>&gt;</span>1.11.0<span class="tag">&lt;/<span class="name">flink.version</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">scala.binary.version</span>&gt;</span>2.11<span class="tag">&lt;/<span class="name">scala.binary.version</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">scala.version</span>&gt;</span>2.11.12<span class="tag">&lt;/<span class="name">scala.version</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">log4j.version</span>&gt;</span>2.12.1<span class="tag">&lt;/<span class="name">log4j.version</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;/<span class="name">properties</span>&gt;</span></span><br><span class="line"></span><br><span class="line">	<span class="tag">&lt;<span class="name">dependencies</span>&gt;</span></span><br><span class="line">		<span class="comment">&lt;!-- Apache Flink dependencies --&gt;</span></span><br><span class="line">		<span class="comment">&lt;!-- These dependencies are provided, because they should not be packaged into the JAR file. --&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.apache.flink<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>flink-scala_$&#123;scala.binary.version&#125;<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">version</span>&gt;</span>$&#123;flink.version&#125;<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!--			&lt;scope&gt;provided&lt;/scope&gt;--&gt;</span></span><br><span class="line">		<span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.apache.flink<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>flink-streaming-scala_$&#123;scala.binary.version&#125;<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">version</span>&gt;</span>$&#123;flink.version&#125;<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!--			&lt;scope&gt;provided&lt;/scope&gt;--&gt;</span></span><br><span class="line">		<span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.apache.flink<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>flink-clients_$&#123;scala.binary.version&#125;<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">version</span>&gt;</span>$&#123;flink.version&#125;<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!--			&lt;scope&gt;provided&lt;/scope&gt;--&gt;</span></span><br><span class="line">		<span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"></span><br><span class="line">		<span class="comment">&lt;!-- Scala Library, provided by Flink as well. --&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.scala-lang<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>scala-library<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">version</span>&gt;</span>$&#123;scala.version&#125;<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!--			&lt;scope&gt;provided&lt;/scope&gt;--&gt;</span></span><br><span class="line">		<span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"></span><br><span class="line">		<span class="comment">&lt;!-- Add connector dependencies here. They must be in the default scope (compile). --&gt;</span></span><br><span class="line"></span><br><span class="line">		<span class="comment">&lt;!-- Example:</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">		&lt;dependency&gt;</span></span><br><span class="line"><span class="comment">			&lt;groupId&gt;org.apache.flink&lt;/groupId&gt;</span></span><br><span class="line"><span class="comment">			&lt;artifactId&gt;flink-connector-kafka_$&#123;scala.binary.version&#125;&lt;/artifactId&gt;</span></span><br><span class="line"><span class="comment">			&lt;version&gt;$&#123;flink.version&#125;&lt;/version&gt;</span></span><br><span class="line"><span class="comment">		&lt;/dependency&gt;</span></span><br><span class="line"><span class="comment">		--&gt;</span></span><br><span class="line"></span><br><span class="line">		<span class="comment">&lt;!-- Add logging framework, to produce console output when running in the IDE. --&gt;</span></span><br><span class="line">		<span class="comment">&lt;!-- These dependencies are excluded from the application JAR by default. --&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.apache.logging.log4j<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>log4j-slf4j-impl<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">version</span>&gt;</span>$&#123;log4j.version&#125;<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">scope</span>&gt;</span>runtime<span class="tag">&lt;/<span class="name">scope</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.apache.logging.log4j<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>log4j-api<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">version</span>&gt;</span>$&#123;log4j.version&#125;<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">scope</span>&gt;</span>runtime<span class="tag">&lt;/<span class="name">scope</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.apache.logging.log4j<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>log4j-core<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">version</span>&gt;</span>$&#123;log4j.version&#125;<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">scope</span>&gt;</span>runtime<span class="tag">&lt;/<span class="name">scope</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;/<span class="name">dependencies</span>&gt;</span></span><br><span class="line"></span><br><span class="line">	<span class="tag">&lt;<span class="name">build</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">plugins</span>&gt;</span></span><br><span class="line">			<span class="comment">&lt;!-- We use the maven-shade plugin to create a fat jar that contains all necessary dependencies. --&gt;</span></span><br><span class="line">			<span class="comment">&lt;!-- Change the value of &lt;mainClass&gt;...&lt;/mainClass&gt; if your program entry point changes. --&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">plugin</span>&gt;</span></span><br><span class="line">				<span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.apache.maven.plugins<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">				<span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>maven-shade-plugin<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">				<span class="tag">&lt;<span class="name">version</span>&gt;</span>3.1.1<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">				<span class="tag">&lt;<span class="name">executions</span>&gt;</span></span><br><span class="line">					<span class="comment">&lt;!-- Run shade goal on package phase --&gt;</span></span><br><span class="line">					<span class="tag">&lt;<span class="name">execution</span>&gt;</span></span><br><span class="line">						<span class="tag">&lt;<span class="name">phase</span>&gt;</span>package<span class="tag">&lt;/<span class="name">phase</span>&gt;</span></span><br><span class="line">						<span class="tag">&lt;<span class="name">goals</span>&gt;</span></span><br><span class="line">							<span class="tag">&lt;<span class="name">goal</span>&gt;</span>shade<span class="tag">&lt;/<span class="name">goal</span>&gt;</span></span><br><span class="line">						<span class="tag">&lt;/<span class="name">goals</span>&gt;</span></span><br><span class="line">						<span class="tag">&lt;<span class="name">configuration</span>&gt;</span></span><br><span class="line">							<span class="tag">&lt;<span class="name">artifactSet</span>&gt;</span></span><br><span class="line">								<span class="tag">&lt;<span class="name">excludes</span>&gt;</span></span><br><span class="line">									<span class="tag">&lt;<span class="name">exclude</span>&gt;</span>org.apache.flink:force-shading<span class="tag">&lt;/<span class="name">exclude</span>&gt;</span></span><br><span class="line">									<span class="tag">&lt;<span class="name">exclude</span>&gt;</span>com.google.code.findbugs:jsr305<span class="tag">&lt;/<span class="name">exclude</span>&gt;</span></span><br><span class="line">									<span class="tag">&lt;<span class="name">exclude</span>&gt;</span>org.slf4j:*<span class="tag">&lt;/<span class="name">exclude</span>&gt;</span></span><br><span class="line">									<span class="tag">&lt;<span class="name">exclude</span>&gt;</span>org.apache.logging.log4j:*<span class="tag">&lt;/<span class="name">exclude</span>&gt;</span></span><br><span class="line">								<span class="tag">&lt;/<span class="name">excludes</span>&gt;</span></span><br><span class="line">							<span class="tag">&lt;/<span class="name">artifactSet</span>&gt;</span></span><br><span class="line">							<span class="tag">&lt;<span class="name">filters</span>&gt;</span></span><br><span class="line">								<span class="tag">&lt;<span class="name">filter</span>&gt;</span></span><br><span class="line">									<span class="comment">&lt;!-- Do not copy the signatures in the META-INF folder.</span></span><br><span class="line"><span class="comment">									Otherwise, this might cause SecurityExceptions when using the JAR. --&gt;</span></span><br><span class="line">									<span class="tag">&lt;<span class="name">artifact</span>&gt;</span>*:*<span class="tag">&lt;/<span class="name">artifact</span>&gt;</span></span><br><span class="line">									<span class="tag">&lt;<span class="name">excludes</span>&gt;</span></span><br><span class="line">										<span class="tag">&lt;<span class="name">exclude</span>&gt;</span>META-INF/*.SF<span class="tag">&lt;/<span class="name">exclude</span>&gt;</span></span><br><span class="line">										<span class="tag">&lt;<span class="name">exclude</span>&gt;</span>META-INF/*.DSA<span class="tag">&lt;/<span class="name">exclude</span>&gt;</span></span><br><span class="line">										<span class="tag">&lt;<span class="name">exclude</span>&gt;</span>META-INF/*.RSA<span class="tag">&lt;/<span class="name">exclude</span>&gt;</span></span><br><span class="line">									<span class="tag">&lt;/<span class="name">excludes</span>&gt;</span></span><br><span class="line">								<span class="tag">&lt;/<span class="name">filter</span>&gt;</span></span><br><span class="line">							<span class="tag">&lt;/<span class="name">filters</span>&gt;</span></span><br><span class="line">							<span class="tag">&lt;<span class="name">transformers</span>&gt;</span></span><br><span class="line">								<span class="tag">&lt;<span class="name">transformer</span> <span class="attr">implementation</span>=<span class="string">&quot;org.apache.maven.plugins.shade.resource.ManifestResourceTransformer&quot;</span>&gt;</span></span><br><span class="line">									<span class="tag">&lt;<span class="name">mainClass</span>&gt;</span>com.caixianquan.WordCount<span class="tag">&lt;/<span class="name">mainClass</span>&gt;</span></span><br><span class="line">								<span class="tag">&lt;/<span class="name">transformer</span>&gt;</span></span><br><span class="line">							<span class="tag">&lt;/<span class="name">transformers</span>&gt;</span></span><br><span class="line">						<span class="tag">&lt;/<span class="name">configuration</span>&gt;</span></span><br><span class="line">					<span class="tag">&lt;/<span class="name">execution</span>&gt;</span></span><br><span class="line">				<span class="tag">&lt;/<span class="name">executions</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;/<span class="name">plugin</span>&gt;</span></span><br><span class="line"></span><br><span class="line">			<span class="comment">&lt;!-- Java Compiler --&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">plugin</span>&gt;</span></span><br><span class="line">				<span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.apache.maven.plugins<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">				<span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>maven-compiler-plugin<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">				<span class="tag">&lt;<span class="name">version</span>&gt;</span>3.1<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">				<span class="tag">&lt;<span class="name">configuration</span>&gt;</span></span><br><span class="line">					<span class="tag">&lt;<span class="name">source</span>&gt;</span>1.8<span class="tag">&lt;/<span class="name">source</span>&gt;</span></span><br><span class="line">					<span class="tag">&lt;<span class="name">target</span>&gt;</span>1.8<span class="tag">&lt;/<span class="name">target</span>&gt;</span></span><br><span class="line">				<span class="tag">&lt;/<span class="name">configuration</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;/<span class="name">plugin</span>&gt;</span></span><br><span class="line"></span><br><span class="line">			<span class="comment">&lt;!-- Scala Compiler --&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">plugin</span>&gt;</span></span><br><span class="line">				<span class="tag">&lt;<span class="name">groupId</span>&gt;</span>net.alchim31.maven<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">				<span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>scala-maven-plugin<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">				<span class="tag">&lt;<span class="name">version</span>&gt;</span>3.2.2<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">				<span class="tag">&lt;<span class="name">executions</span>&gt;</span></span><br><span class="line">					<span class="tag">&lt;<span class="name">execution</span>&gt;</span></span><br><span class="line">						<span class="tag">&lt;<span class="name">goals</span>&gt;</span></span><br><span class="line">							<span class="tag">&lt;<span class="name">goal</span>&gt;</span>compile<span class="tag">&lt;/<span class="name">goal</span>&gt;</span></span><br><span class="line">							<span class="tag">&lt;<span class="name">goal</span>&gt;</span>testCompile<span class="tag">&lt;/<span class="name">goal</span>&gt;</span></span><br><span class="line">						<span class="tag">&lt;/<span class="name">goals</span>&gt;</span></span><br><span class="line">					<span class="tag">&lt;/<span class="name">execution</span>&gt;</span></span><br><span class="line">				<span class="tag">&lt;/<span class="name">executions</span>&gt;</span></span><br><span class="line">				<span class="tag">&lt;<span class="name">configuration</span>&gt;</span></span><br><span class="line">					<span class="tag">&lt;<span class="name">args</span>&gt;</span></span><br><span class="line">						<span class="tag">&lt;<span class="name">arg</span>&gt;</span>-nobootcp<span class="tag">&lt;/<span class="name">arg</span>&gt;</span></span><br><span class="line">					<span class="tag">&lt;/<span class="name">args</span>&gt;</span></span><br><span class="line">				<span class="tag">&lt;/<span class="name">configuration</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;/<span class="name">plugin</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">plugin</span>&gt;</span></span><br><span class="line">				<span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.codehaus.mojo<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">				<span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>build-helper-maven-plugin<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">				<span class="tag">&lt;<span class="name">version</span>&gt;</span>1.7<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">				<span class="tag">&lt;<span class="name">executions</span>&gt;</span></span><br><span class="line">					<span class="comment">&lt;!-- Add src/main/scala to eclipse build path --&gt;</span></span><br><span class="line">					<span class="tag">&lt;<span class="name">execution</span>&gt;</span></span><br><span class="line">						<span class="tag">&lt;<span class="name">id</span>&gt;</span>add-source<span class="tag">&lt;/<span class="name">id</span>&gt;</span></span><br><span class="line">						<span class="tag">&lt;<span class="name">phase</span>&gt;</span>generate-sources<span class="tag">&lt;/<span class="name">phase</span>&gt;</span></span><br><span class="line">						<span class="tag">&lt;<span class="name">goals</span>&gt;</span></span><br><span class="line">							<span class="tag">&lt;<span class="name">goal</span>&gt;</span>add-source<span class="tag">&lt;/<span class="name">goal</span>&gt;</span></span><br><span class="line">						<span class="tag">&lt;/<span class="name">goals</span>&gt;</span></span><br><span class="line">						<span class="tag">&lt;<span class="name">configuration</span>&gt;</span></span><br><span class="line">							<span class="tag">&lt;<span class="name">sources</span>&gt;</span></span><br><span class="line">								<span class="tag">&lt;<span class="name">source</span>&gt;</span>src/main/scala<span class="tag">&lt;/<span class="name">source</span>&gt;</span></span><br><span class="line">							<span class="tag">&lt;/<span class="name">sources</span>&gt;</span></span><br><span class="line">						<span class="tag">&lt;/<span class="name">configuration</span>&gt;</span></span><br><span class="line">					<span class="tag">&lt;/<span class="name">execution</span>&gt;</span></span><br><span class="line">					<span class="comment">&lt;!-- Add src/test/scala to eclipse build path --&gt;</span></span><br><span class="line">					<span class="tag">&lt;<span class="name">execution</span>&gt;</span></span><br><span class="line">						<span class="tag">&lt;<span class="name">id</span>&gt;</span>add-test-source<span class="tag">&lt;/<span class="name">id</span>&gt;</span></span><br><span class="line">						<span class="tag">&lt;<span class="name">phase</span>&gt;</span>generate-test-sources<span class="tag">&lt;/<span class="name">phase</span>&gt;</span></span><br><span class="line">						<span class="tag">&lt;<span class="name">goals</span>&gt;</span></span><br><span class="line">							<span class="tag">&lt;<span class="name">goal</span>&gt;</span>add-test-source<span class="tag">&lt;/<span class="name">goal</span>&gt;</span></span><br><span class="line">						<span class="tag">&lt;/<span class="name">goals</span>&gt;</span></span><br><span class="line">						<span class="tag">&lt;<span class="name">configuration</span>&gt;</span></span><br><span class="line">							<span class="tag">&lt;<span class="name">sources</span>&gt;</span></span><br><span class="line">								<span class="tag">&lt;<span class="name">source</span>&gt;</span>src/test/scala<span class="tag">&lt;/<span class="name">source</span>&gt;</span></span><br><span class="line">							<span class="tag">&lt;/<span class="name">sources</span>&gt;</span></span><br><span class="line">						<span class="tag">&lt;/<span class="name">configuration</span>&gt;</span></span><br><span class="line">					<span class="tag">&lt;/<span class="name">execution</span>&gt;</span></span><br><span class="line">				<span class="tag">&lt;/<span class="name">executions</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;/<span class="name">plugin</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;/<span class="name">plugins</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;/<span class="name">build</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">project</span>&gt;</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h2 id="运行程序"><a href="#运行程序" class="headerlink" title="运行程序"></a>运行程序</h2></li>
<li>在监听的Linux主机上敲下命令：nc -lk 9999</li>
<li>idea运行程序</li>
<li>在终端中输入字符串，观察程序输出<br><img src="6%E3%80%81%E6%9F%A5%E7%9C%8B%E7%A8%8B%E5%BA%8F%E8%BF%90%E8%A1%8C%E7%BB%93%E6%9E%9C.png" alt="查看程序运行结果"></li>
</ol>
<h1 id="Flink部署"><a href="#Flink部署" class="headerlink" title="Flink部署"></a>Flink部署</h1><div class="note info flat"><p>安装flink参考地址：<a target="_blank" rel="noopener" href="https://www.caixianquan.tk/2020/11/16/%E5%A4%A7%E6%95%B0%E6%8D%AEspark%E7%AD%89%E7%BB%84%E4%BB%B6%E6%90%AD%E5%BB%BA-%E4%B8%89/">https://www.caixianquan.tk/2020/11/16/大数据spark等组件搭建-三/</a></p>
</div>

<h2 id="Session-Cluster提交任务"><a href="#Session-Cluster提交任务" class="headerlink" title="Session Cluster提交任务"></a>Session Cluster提交任务</h2><p>在yarn中初始化一个flink集群，开辟指定的资源，以后提交任务都向这里提交。这个flink集群会常驻在yarn集群中，除非手工停止。</p>
<ol>
<li>先启动hadoop集群</li>
<li>启动flink集群</li>
<li>启动yarn-session【在flink/bin下】：<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./yarn-session.sh -n 2 -s 2 -jm 1024 -tm 1024 -nm test -d</span><br></pre></td></tr></table></figure>
其中：</li>
</ol>
<ul>
<li>-n(–container)：TaskManager的数量。</li>
<li>-s(–slots)：    每个TaskManager的slot数量，默认一个slot一个core，默认每个taskmanager的slot的个数为1，有时可以多一些taskmanager，做冗余。</li>
<li>-jm：JobManager的内存（单位MB)。</li>
<li>-tm：每个taskmanager的内存（单位MB)。</li>
<li>-nm：yarn 的appName(现在yarn的ui上的名字)。 </li>
<li>-d：后台执行。</li>
</ul>
<ol start="4">
<li>执行任务：<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">flink run  /opt/module/flink-1.10.0/examples/batch/WordCount.jar</span><br></pre></td></tr></table></figure>
<h2 id="Per-Job-Cluster提交任务"><a href="#Per-Job-Cluster提交任务" class="headerlink" title="Per Job Cluster提交任务"></a>Per Job Cluster提交任务</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">flink run -m yarn-cluster /opt/module/flink-1.10.0/examples/batch/WordCount.jar</span><br></pre></td></tr></table></figure>
<h2 id="查看日志"><a href="#查看日志" class="headerlink" title="查看日志"></a>查看日志</h2></li>
<li>Session Cluster模式下可以通过Yarn UI中的运行任务下的ApplicationMaster进入查看Flink任务管理页面；Job Cluster模式可以通过<a href="http://hadoop101:8081来访问任务">http://hadoop101:8081来访问任务</a></li>
<li>Session Cluster模式下只有停止所在的yarn任务才能够使用yarn logs 来收集taskmanager中的日志</li>
<li>Flink应用暂时无法打印自定义的log日志，只能只能通过print打印出来</li>
</ol>
<h1 id="Flink运行架构"><a href="#Flink运行架构" class="headerlink" title="Flink运行架构"></a>Flink运行架构</h1><h2 id="Flink运行时组件"><a href="#Flink运行时组件" class="headerlink" title="Flink运行时组件"></a>Flink运行时组件</h2><p>Flink运行时架构主要包括四个不同的组件，它们会在运行流处理应用程序时协同工作：作业管理器（JobManager）【类似于master】、资源管理器（ResourceManager）、任务管理器（TaskManager）【类似于slave】，以及分发器（Dispatcher）。因为Flink是用Java和Scala实现的，所以所有组件都会运行在Java虚拟机（JVMs）上。每个组件的职责如下：</p>
<ol>
<li><p>作业管理器（JobManager）是控制一个应用程序执行的主进程，也就是说，每个应用程序都会被一个不同的作业管理器所控制执行。</p>
<ul>
<li>作业管理器会先接收到要执行的应用程序。这个应用程序会包括：作业图（JobGraph）、逻辑数据流图（logical dataflow graph）和打包了所有的类、库和其它资源的JAR包。</li>
<li>作业管理器会把JobGraph转换成一个物理层面的数据流图，这个图被叫做“执行图”（ExecutionGraph），包含了所有可以并发执行的任务。</li>
<li>作业管理器会向资源管理器（ResourceManager）请求执行任务必要的资源，也就是任务管理器（TaskManager）上的插槽（slot）。一旦它获取到了足够的资源，就会将执行图分发到真正运行它们的TaskManager上。</li>
<li>而在运行过程中，作业管理器会负责所有需要中央协调的操作，比如说检查点（checkpoints）的协调。</li>
</ul>
</li>
<li><p>ResourceManager主要负责管理任务管理器（TaskManager）的插槽（slot）【类似spark中的分区】，TaskManger插槽是Flink中定义的处理资源单元。</p>
<ul>
<li>Flink为不同的环境和资源管理工具提供了不同资源管理器（ResourceManager），比如YARN、Mesos、K8s，以及standalone部署。</li>
<li>当作业管理器申请插槽资源时，ResourceManager会将有空闲插槽的TaskManager分配给作业管理器。如果ResourceManager没有足够的插槽来满足作业管理器的请求，它还可以向资源提供平台发起会话，以提供启动TaskManager进程的容器。</li>
<li>另外，ResourceManager还负责终止空闲的TaskManager，释放计算资源。</li>
</ul>
</li>
<li><p>任务管理器（TaskManager）是Flink中的工作进程。</p>
<ul>
<li>通常在Flink中会有多个TaskManager运行，每一个TaskManager都包含了一定数量的插槽（slots）。插槽的数量限制了TaskManager能够执行的任务数量。</li>
<li>启动之后，TaskManager会向资源管理器注册它的插槽；收到资源管理器的指令后，TaskManager就会将一个或者多个插槽提供给作业管理器调用。作业管理器就可以向插槽分配任务（tasks）来执行了。</li>
<li>在执行过程中，一个TaskManager可以跟其它运行同一应用程序的TaskManager交换数据（比如shuffle）。任务的执行和插槽的概念会在“任务执行”一节做具体讨论。</li>
<li>每一个任务管理器是一个JVM进程，每一个插槽是一个线程。</li>
</ul>
</li>
<li><p>分发器（Dispatcher）可以跨作业运行，它为应用提交提供了REST接口。</p>
<ul>
<li>当一个应用被提交执行时，分发器就会启动并将应用移交给一个作业管理器。由于是REST接口，所以Dispatcher可以作为集群的一个HTTP接入点，这样就能够不受防火墙阻挡。</li>
<li>Dispatcher也会启动一个Web UI，用来方便地展示和监控作业执行的信息。</li>
<li>Dispatcher在架构中可能并不是必需的，这取决于应用提交运行的方式。</li>
</ul>
</li>
</ol>
<h2 id="任务提交流程（独立集群）"><a href="#任务提交流程（独立集群）" class="headerlink" title="任务提交流程（独立集群）"></a>任务提交流程（独立集群）</h2><p><img src="9%E3%80%81%E7%8B%AC%E7%AB%8B%E9%9B%86%E7%BE%A4%E7%9A%84%E4%BB%BB%E5%8A%A1%E6%8F%90%E4%BA%A4%E6%B5%81%E7%A8%8B.png" alt="独立集群的任务提交流程"></p>
<ol>
<li>程序的并行度设置为10，那么并行任务的数量就是10，作业管理器就会向资源管理器请求10个任务槽<br><img src="10%E3%80%81yarn%E5%BD%A2%E5%BC%8F%E7%9A%84%E4%BB%BB%E5%8A%A1%E6%8F%90%E4%BA%A4%E6%B5%81%E7%A8%8B.png" alt="yarn形式的任务提交流程"><br><img src="11%E3%80%81%E4%BB%BB%E5%8A%A1%E8%B0%83%E5%BA%A6%E5%8E%9F%E7%90%86.png" alt="任务调度原理"><br><img src="12%E3%80%81TaskManager%E5%92%8CSlots.png" alt="TaskManager和Slots"></li>
<li>Flink中每一个TaskManager都是一个JVM进程，每一个任务插槽都会启动一个线程，它可能会在独立的线程上执行一个或多个子任务【顺序执行】，每一个子任务占用一个任务插槽（Task slot）</li>
<li>为了控制一个TaskManager能接收多少个task，TaskManager通过task slot 来进行控制（一个TaskManager至少有一个slot）</li>
<li>默认情况下，Flink允许子任务共享slot，即使它们是不同任务的子任务。 这样的结果是，一个slot可以保存作业的整个管道。</li>
<li>Task Slot是静态的概念，是指TaskManager具有的并发执行能力<br><img src="13%E3%80%81%E4%BB%BB%E5%8A%A1%E6%A7%BD%E6%95%B0%E9%87%8F%E7%A4%BA%E4%BE%8B.png" alt="任务槽数量示例"></li>
</ol>
<ul>
<li>flink-conf.yaml中配置的任务槽是一个taskmanager有3个slot，而代码中的并行度设置为1，那么任务就只会启动一个slot来执行任务，而设置为2时，那么每一个算子就会在两个slot中执行<br><img src="14%E3%80%81%E4%BB%BB%E5%8A%A1%E6%A7%BD%E5%8D%A0%E6%BB%A1%E4%BE%8B%E5%AD%90.png" alt="任务槽占满例子"></li>
<li>而如果设置并行度为9，那么三个taskmanager中的三个任务槽都会被占用执行</li>
<li>可以单独设置不同算子的并行度，比如sink设置为1，如Example4</li>
<li>taskmanager安装在几个节点上就会启动多少个taskmanager进程，即可认为是节点的数量</li>
</ul>
<h2 id="程序与数据流（DataFlow）"><a href="#程序与数据流（DataFlow）" class="headerlink" title="程序与数据流（DataFlow）"></a>程序与数据流（DataFlow）</h2><p><img src="15%E3%80%81%E7%A8%8B%E5%BA%8F%E4%B8%8E%E6%95%B0%E6%8D%AE%E6%B5%81.png" alt="程序与数据流"></p>
<ol>
<li>所有的Flink程序都是由三部分组成的：  Source 、Transformation 和 Sink。</li>
<li>Source 负责读取数据源，Transformation 利用各种算子进行处理加工，Sink 负责输出</li>
<li>在运行时，Flink上运行的程序会被映射成“逻辑数据流”（dataflows），它包含了这三部分</li>
<li>每一个dataflow以一个或多个sources开始以一个或多个sinks结束。dataflow类似于任意的有向无环图（DAG）</li>
<li>在大部分情况下，程序中的转换运算（transformations）跟dataflow中的算子（operator）是一一对应的关系<br><img src="16%E3%80%81%E6%95%B0%E6%8D%AE%E6%B5%81%E6%9C%89%E5%90%91%E6%97%A0%E7%8E%AF%E5%9B%BE.png" alt="数据流有向无环图"></li>
</ol>
<h2 id="执行图（ExecutionGraph）"><a href="#执行图（ExecutionGraph）" class="headerlink" title="执行图（ExecutionGraph）"></a>执行图（ExecutionGraph）</h2><ol>
<li>Flink中的执行图可以分成四层：StreamGraph -&gt; JobGraph -&gt; ExecutionGraph -&gt; 物理执行图</li>
<li>StreamGraph：是根据用户通过 Stream API编写的代码生成的最初的图。用来表示程序的拓扑结构。</li>
<li>JobGraph：StreamGraph在编译的阶段经过优化后生成了 JobGraph，提交给 JobManager 的数据结构。主要的优化为，将多个符合条件的节点 chain 在一起作为一个节点</li>
<li>ExecutionGraph：JobManager 根据 JobGraph 生成ExecutionGraph。ExecutionGraph是JobGraph的并行化版本，是调度层最核心的数据结构。</li>
<li>物理执行图：JobManager根据ExecutionGraph对Job进行调度后，在各个TaskManager上部署Task后形成的“图”，并不是一个具体的数据结构。<br><img src="17%E3%80%81%E6%89%A7%E8%A1%8C%E5%9B%BE%E8%BD%AC%E6%8D%A2.png" alt="执行图转换"></li>
</ol>
<h2 id="并行度（Parallelism）"><a href="#并行度（Parallelism）" class="headerlink" title="并行度（Parallelism）"></a>并行度（Parallelism）</h2><p><img src="18%E3%80%81%E5%B9%B6%E8%A1%8C%E5%BA%A6.png" alt="并行度"></p>
<ol>
<li>一个特定算子的子任务（subtask）的个数被称之为其并行度（parallelism）。一般情况下，一个stream的并行度，可以认为就是其所有算子中最大的并行度。</li>
<li>程序设置的并行度要小于或等于配置文件中设置的所有taskmanager的slot数量，否则程序会报错。</li>
</ol>
<h2 id="任务链（Operator-Chains）"><a href="#任务链（Operator-Chains）" class="headerlink" title="任务链（Operator Chains）"></a>任务链（Operator Chains）</h2><ol>
<li>Flink采用了一种称为任务链的优化技术，可以在特定条件下减少本地通信的开销。为了满足任务链的要求，必须将两个或多个算子设为相同的并行度，并通过本地转发（local forward）的方式进行连接</li>
<li>相同并行度的one-to-one操作，Flink这样相连的算子链接在一起形成一个task，原来的算子成为里面的subtask</li>
<li><font color=red size=3><strong><em>并行度相同、并且是 one-to-one 操作，两个条件缺一不可</em></strong></font><br><img src="19%E3%80%81%E4%BB%BB%E5%8A%A1%E9%93%BE.png" alt="任务链"></li>
</ol>
<h1 id=""><a href="#" class="headerlink" title=""></a></h1><p><img src="example.png" alt="example"><br><img src="example.png" alt="example"><br><img src="example.png" alt="example"><br><img src="example.png" alt="example"></p>
</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">文章作者: </span><span class="post-copyright-info"><a href="mailto:undefined">Cai XianQuan</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">文章链接: </span><span class="post-copyright-info"><a href="https://xquan123.gitee.io/2020/12/13/Flink%E5%85%A5%E9%97%A8%E5%AD%A6%E4%B9%A0/">https://xquan123.gitee.io/2020/12/13/Flink%E5%85%A5%E9%97%A8%E5%AD%A6%E4%B9%A0/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://xquan123.gitee.io" target="_blank">Cquang博客</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/blog/tags/%E5%A4%A7%E6%95%B0%E6%8D%AE/">大数据</a><a class="post-meta__tags" href="/blog/tags/flink/">flink</a></div><div class="post_share"><div class="social-share" data-image="/blog/2020/12/13/Flink%E5%85%A5%E9%97%A8%E5%AD%A6%E4%B9%A0/Flink%E5%85%A5%E9%97%A8%E5%AD%A6%E4%B9%A0%E9%A6%96%E9%A1%B5.png" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/social-share.js/dist/css/share.min.css"><script src="https://cdn.jsdelivr.net/npm/social-share.js/dist/js/social-share.min.js" defer></script></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/blog/2020/12/13/%E5%B8%B8%E7%94%A8%E7%9A%84Linux%E5%91%BD%E4%BB%A4%E9%9B%86/"><img class="prev-cover" src="/blog/2020/12/13/%E5%B8%B8%E7%94%A8%E7%9A%84Linux%E5%91%BD%E4%BB%A4%E9%9B%86/%E5%B8%B8%E7%94%A8%E7%9A%84Linux%E5%91%BD%E4%BB%A4%E9%9B%86%E9%A6%96%E9%A1%B5.jpg" onerror="onerror=null;src='/blog/img/404.jpg'"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">常用的Linux命令集</div></div></a></div><div class="next-post pull-right"><a href="/blog/2020/12/08/kafka%E5%85%A5%E9%97%A8%E5%AD%A6%E4%B9%A0/"><img class="next-cover" src="/blog/2020/12/08/kafka%E5%85%A5%E9%97%A8%E5%AD%A6%E4%B9%A0/kafka%E5%85%A5%E9%97%A8%E5%AD%A6%E4%B9%A0%E9%A6%96%E9%A1%B5.png" onerror="onerror=null;src='/blog/img/404.jpg'"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">kafka入门学习</div></div></a></div></nav><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span> 相关推荐</span></div><div class="relatedPosts-list"><div><a href="/blog/2020/12/08/kafka入门学习/" title="kafka入门学习"><img class="cover" src="/blog/2020/12/08/kafka%E5%85%A5%E9%97%A8%E5%AD%A6%E4%B9%A0/kafka%E5%85%A5%E9%97%A8%E5%AD%A6%E4%B9%A0%E9%A6%96%E9%A1%B5.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2020-12-08</div><div class="title">kafka入门学习</div></div></a></div><div><a href="/blog/2020/08/08/尚硅谷大数据之Spark基础解析-一/" title="尚硅谷大数据之Spark基础解析(一)"><img class="cover" src="/blog/2020/08/08/%E5%B0%9A%E7%A1%85%E8%B0%B7%E5%A4%A7%E6%95%B0%E6%8D%AE%E4%B9%8BSpark%E5%9F%BA%E7%A1%80%E8%A7%A3%E6%9E%90-%E4%B8%80/%E5%B0%9A%E7%A1%85%E8%B0%B7%E5%A4%A7%E6%95%B0%E6%8D%AE%E4%B9%8BSpark%E5%9F%BA%E7%A1%80%E8%A7%A3%E6%9E%90%E9%A6%96%E9%A1%B5.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2020-08-08</div><div class="title">尚硅谷大数据之Spark基础解析(一)</div></div></a></div></div></div></div><div class="aside_content" id="aside_content"><div class="card-widget card-info"><div class="card-content"><div class="card-info-avatar is-center"><img class="avatar-img" src="/blog/img/%E5%A4%B4%E5%83%8F.gif" onerror="this.onerror=null;this.src='/blog/img/friend_404.gif'" alt="avatar"/><div class="author-info__name">Cai XianQuan</div><div class="author-info__description"></div></div><div class="card-info-data"><div class="card-info-data-item is-center"><a href="/blog/archives/"><div class="headline">文章</div><div class="length-num">22</div></a></div><div class="card-info-data-item is-center"><a href="/blog/tags/"><div class="headline">标签</div><div class="length-num">33</div></a></div><div class="card-info-data-item is-center"><a href="/blog/categories/"><div class="headline">分类</div><div class="length-num">18</div></a></div></div><a class="button--animated" id="card-info-btn" href="javascript:;"><i class="fab fa-bookmark"></i><span>加入书签</span></a></div></div><div class="card-widget card-announcement"><div class="card-content"><div class="item-headline"><i class="fas fa-bullhorn card-announcement-animation"></i><span>公告</span></div><div class="announcement_content">一花一世界,一木一菩提╮(￣▽ ￣)╭</div></div></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="card-content"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#Flink%E7%AE%80%E4%BB%8B"><span class="toc-number">1.</span> <span class="toc-text">Flink简介</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%A4%A7%E6%95%B0%E6%8D%AE%E6%A1%86%E6%9E%B6%E7%9A%84%E5%8F%91%E5%B1%95%E5%8E%86%E7%A8%8B"><span class="toc-number">1.1.</span> <span class="toc-text">大数据框架的发展历程</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%88%9D%E8%AF%86Flink"><span class="toc-number">1.2.</span> <span class="toc-text">初识Flink</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%80%89%E6%8B%A9Flink%E7%9A%84%E7%90%86%E7%94%B1"><span class="toc-number">1.2.1.</span> <span class="toc-text">选择Flink的理由</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%93%AA%E4%BA%9B%E8%A1%8C%E4%B8%9A%E9%9C%80%E8%A6%81%E5%A4%84%E7%90%86%E6%B5%81%E6%95%B0%E6%8D%AE"><span class="toc-number">1.2.2.</span> <span class="toc-text">哪些行业需要处理流数据</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Flink%E7%9A%84%E9%87%8D%E8%A6%81%E7%89%B9%E7%82%B9"><span class="toc-number">1.3.</span> <span class="toc-text">Flink的重要特点</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BA%8B%E4%BB%B6%E9%A9%B1%E5%8A%A8%E5%9E%8B-Event-driven"><span class="toc-number">1.3.1.</span> <span class="toc-text">事件驱动型(Event-driven)</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%B5%81%E4%B8%8E%E6%89%B9%E7%9A%84%E4%B8%96%E7%95%8C%E8%A7%82"><span class="toc-number">1.3.2.</span> <span class="toc-text">流与批的世界观</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%88%86%E5%B1%82api"><span class="toc-number">1.3.3.</span> <span class="toc-text">分层api</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Flink%E7%9A%84%E5%85%B6%E4%BB%96%E7%89%B9%E7%82%B9"><span class="toc-number">1.3.4.</span> <span class="toc-text">Flink的其他特点</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#wordCount%E7%A8%8B%E5%BA%8F"><span class="toc-number">2.</span> <span class="toc-text">wordCount程序</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E9%9C%80%E6%B1%82%E8%AF%B4%E6%98%8E"><span class="toc-number">2.1.</span> <span class="toc-text">需求说明</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%A8%8B%E5%BA%8F%E7%BC%96%E5%86%99"><span class="toc-number">2.2.</span> <span class="toc-text">程序编写</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#pom%E6%96%87%E4%BB%B6%E4%BF%AE%E6%94%B9"><span class="toc-number">2.3.</span> <span class="toc-text">pom文件修改</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%BF%90%E8%A1%8C%E7%A8%8B%E5%BA%8F"><span class="toc-number">2.4.</span> <span class="toc-text">运行程序</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#Flink%E9%83%A8%E7%BD%B2"><span class="toc-number">3.</span> <span class="toc-text">Flink部署</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#Session-Cluster%E6%8F%90%E4%BA%A4%E4%BB%BB%E5%8A%A1"><span class="toc-number">3.1.</span> <span class="toc-text">Session Cluster提交任务</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Per-Job-Cluster%E6%8F%90%E4%BA%A4%E4%BB%BB%E5%8A%A1"><span class="toc-number">3.2.</span> <span class="toc-text">Per Job Cluster提交任务</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%9F%A5%E7%9C%8B%E6%97%A5%E5%BF%97"><span class="toc-number">3.3.</span> <span class="toc-text">查看日志</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#Flink%E8%BF%90%E8%A1%8C%E6%9E%B6%E6%9E%84"><span class="toc-number">4.</span> <span class="toc-text">Flink运行架构</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#Flink%E8%BF%90%E8%A1%8C%E6%97%B6%E7%BB%84%E4%BB%B6"><span class="toc-number">4.1.</span> <span class="toc-text">Flink运行时组件</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BB%BB%E5%8A%A1%E6%8F%90%E4%BA%A4%E6%B5%81%E7%A8%8B%EF%BC%88%E7%8B%AC%E7%AB%8B%E9%9B%86%E7%BE%A4%EF%BC%89"><span class="toc-number">4.2.</span> <span class="toc-text">任务提交流程（独立集群）</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%A8%8B%E5%BA%8F%E4%B8%8E%E6%95%B0%E6%8D%AE%E6%B5%81%EF%BC%88DataFlow%EF%BC%89"><span class="toc-number">4.3.</span> <span class="toc-text">程序与数据流（DataFlow）</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%89%A7%E8%A1%8C%E5%9B%BE%EF%BC%88ExecutionGraph%EF%BC%89"><span class="toc-number">4.4.</span> <span class="toc-text">执行图（ExecutionGraph）</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%B9%B6%E8%A1%8C%E5%BA%A6%EF%BC%88Parallelism%EF%BC%89"><span class="toc-number">4.5.</span> <span class="toc-text">并行度（Parallelism）</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BB%BB%E5%8A%A1%E9%93%BE%EF%BC%88Operator-Chains%EF%BC%89"><span class="toc-number">4.6.</span> <span class="toc-text">任务链（Operator Chains）</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link"><span class="toc-number">5.</span> <span class="toc-text"></span></a></li></ol></div></div></div><div class="card-widget card-recent-post"><div class="card-content"><div class="item-headline"><i class="fas fa-history"></i><span>最新文章</span></div><div class="aside-list"><div class="aside-list-item"><a class="thumbnail" href="/blog/2021/01/29/%E6%A1%86%E6%9E%B6%E5%A5%97%E8%B7%AF%E8%A7%A3%E7%AE%97%E6%B3%95/" title="框架套路解算法"><img src="/blog/2021/01/29/%E6%A1%86%E6%9E%B6%E5%A5%97%E8%B7%AF%E8%A7%A3%E7%AE%97%E6%B3%95/%E6%A1%86%E6%9E%B6%E5%A5%97%E8%B7%AF%E8%A7%A3%E7%AE%97%E6%B3%95%E9%A6%96%E9%A1%B5.jpg" onerror="this.onerror=null;this.src='/blog/img/404.jpg'" alt="框架套路解算法"/></a><div class="content"><a class="title" href="/blog/2021/01/29/%E6%A1%86%E6%9E%B6%E5%A5%97%E8%B7%AF%E8%A7%A3%E7%AE%97%E6%B3%95/" title="框架套路解算法">框架套路解算法</a><time datetime="2021-01-29T07:37:55.000Z" title="发表于 2021-01-29 15:37:55">2021-01-29</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/blog/2021/01/07/shell%E8%84%9A%E6%9C%AC%E5%AD%A6%E4%B9%A0/" title="shell脚本学习"><img src="/blog/2021/01/07/shell%E8%84%9A%E6%9C%AC%E5%AD%A6%E4%B9%A0/shell%E8%84%9A%E6%9C%AC%E5%AD%A6%E4%B9%A0%E9%A6%96%E9%A1%B5.jpg" onerror="this.onerror=null;this.src='/blog/img/404.jpg'" alt="shell脚本学习"/></a><div class="content"><a class="title" href="/blog/2021/01/07/shell%E8%84%9A%E6%9C%AC%E5%AD%A6%E4%B9%A0/" title="shell脚本学习">shell脚本学习</a><time datetime="2021-01-07T03:29:18.000Z" title="发表于 2021-01-07 11:29:18">2021-01-07</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/blog/2020/12/28/Linux%E9%97%AE%E9%A2%98%E9%9B%86%E9%94%A6/" title="Linux问题集锦"><img src="/blog/2020/12/28/Linux%E9%97%AE%E9%A2%98%E9%9B%86%E9%94%A6/Linux%E9%97%AE%E9%A2%98%E9%9B%86%E9%94%A6%E9%A6%96%E9%A1%B5.png" onerror="this.onerror=null;this.src='/blog/img/404.jpg'" alt="Linux问题集锦"/></a><div class="content"><a class="title" href="/blog/2020/12/28/Linux%E9%97%AE%E9%A2%98%E9%9B%86%E9%94%A6/" title="Linux问题集锦">Linux问题集锦</a><time datetime="2020-12-28T01:56:38.000Z" title="发表于 2020-12-28 09:56:38">2020-12-28</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/blog/2020/12/13/%E5%B8%B8%E7%94%A8%E7%9A%84Linux%E5%91%BD%E4%BB%A4%E9%9B%86/" title="常用的Linux命令集"><img src="/blog/2020/12/13/%E5%B8%B8%E7%94%A8%E7%9A%84Linux%E5%91%BD%E4%BB%A4%E9%9B%86/%E5%B8%B8%E7%94%A8%E7%9A%84Linux%E5%91%BD%E4%BB%A4%E9%9B%86%E9%A6%96%E9%A1%B5.jpg" onerror="this.onerror=null;this.src='/blog/img/404.jpg'" alt="常用的Linux命令集"/></a><div class="content"><a class="title" href="/blog/2020/12/13/%E5%B8%B8%E7%94%A8%E7%9A%84Linux%E5%91%BD%E4%BB%A4%E9%9B%86/" title="常用的Linux命令集">常用的Linux命令集</a><time datetime="2020-12-13T14:32:23.000Z" title="发表于 2020-12-13 22:32:23">2020-12-13</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/blog/2020/12/13/Flink%E5%85%A5%E9%97%A8%E5%AD%A6%E4%B9%A0/" title="Flink入门学习"><img src="/blog/2020/12/13/Flink%E5%85%A5%E9%97%A8%E5%AD%A6%E4%B9%A0/Flink%E5%85%A5%E9%97%A8%E5%AD%A6%E4%B9%A0%E9%A6%96%E9%A1%B5.png" onerror="this.onerror=null;this.src='/blog/img/404.jpg'" alt="Flink入门学习"/></a><div class="content"><a class="title" href="/blog/2020/12/13/Flink%E5%85%A5%E9%97%A8%E5%AD%A6%E4%B9%A0/" title="Flink入门学习">Flink入门学习</a><time datetime="2020-12-13T10:21:57.000Z" title="发表于 2020-12-13 18:21:57">2020-12-13</time></div></div></div></div></div></div></div></main><footer id="footer" style="background-image: url(/blog/2020/12/13/Flink%E5%85%A5%E9%97%A8%E5%AD%A6%E4%B9%A0/Flink%E5%85%A5%E9%97%A8%E5%AD%A6%E4%B9%A0%E9%A6%96%E9%A1%B5.png)"><div id="footer-wrap"><div class="copyright">&copy;2020 - 2021 By Cai XianQuan</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div><div class="footer_custom_text">Hi,  welcome  to  my  <a  target="_blank" rel="noopener" href="https://www.caixianquan.tk">blog</a>!</div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="translateLink" type="button" title="简繁转换">繁</button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up"></i></button></div></div><div id="local-search"><div class="search-dialog"><div class="search-dialog__title" id="local-search-title">本地搜索</div><div id="local-input-panel"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"/></div></div></div><hr/><div id="local-search-results"><div id="local-hits"></div><div id="local-stats"><div class="local-search-stats__hr" id="hr"><span>由</span> <a target="_blank" rel="noopener" href="https://github.com/wzpan/hexo-generator-search" style="color:#49B1F5;">hexo-generator-search</a>
 <span>提供支持</span></div></div></div><span class="search-close-button"><i class="fas fa-times"></i></span></div><div id="search-mask"></div></div><div><script src="https://cdn.jsdelivr.net/npm/jquery@latest/dist/jquery.min.js"></script><script src="/blog/js/utils.js"></script><script src="/blog/js/main.js"></script><script src="/blog/js/tw_cn.js"></script><script src="https://cdn.jsdelivr.net/npm/medium-zoom/dist/medium-zoom.min.js"></script><script src="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.js"></script><script src="/blog/js/search/local-search.js"></script><div class="js-pjax"><script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div><script src="/js/bookmark.js"></script><script defer="defer" id="fluttering_ribbon" mobile="false" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/dist/canvas-fluttering-ribbon.min.js"></script><script id="click-heart" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/dist/click-heart.min.js" async="async" mobile="true"></script></div></body></html>